package com.authine.cloudpivot.ext.controller.DealingUnitInformation;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 总公司往来单位财务信息
 */

@Slf4j
@RestController
@RequestMapping("/public/ZGSDealingUnitFinanceController")
public class ZGSDealingUnitFinanceController extends BaseController {

    @Autowired
    CloudSqlService sqlService;


    /**
     * 总公司往来单位财务信息  审批流完成后 数据写到-总公司往来单位基础信息 基础表，补全基础表的数据
     */
    @RequestMapping("finish")
    public void finish(String bizId) {
        BizObjectFacade bizObjectFacade = getBizObjectFacade();
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject(CustomSchemaCode.ZGS_DealingUnitFinance, bizId);
        //headOfficeDealingUnitDetail  总公司往来单位财务信息 子表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.ZGS_DealingUnitFinanceDetail);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {
            try {
                //将子表中数据处理，随后更新至【总公司往来单位基础信息 基础表】，需要判断是否存在
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //根据往来单位代码查询基础表
                String id = existsBizObject(data);
                if (StringUtils.isNotBlank(id)) {
                    data.put("id", id);
                }


                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.headOfficeDealingUnitBas, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("总公司往来单位基础信息 基础表-新增成功");

                callProcess(id);
            } catch (Exception e) {
                log.info("总公司往来单位基础信息 基础表-操作失败，数据:\n{}", JSONObject.toJSONString(map));
                log.info(e.getMessage(), e);
            }
        }
    }

    @RequestMapping("toVoid")
    public void toVoid(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.voidZGSDealUnitFinance, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.voidZGSDealUnitFinanceDetail);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //获取审批人
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {
            try {
                //将子表中数据处理，随后更新至【总公司往来单位基础信息 基础表】，需要判断是否存在
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                String id = existsBizObject(data);
                if (StringUtils.isNotBlank(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.headOfficeDealingUnitBas, data, false);
                model.setSequenceStatus(SequenceStatus.CANCELED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("总公司往来单位基础信息 基础表  作废操作成功 ");
                //调用存储过程
                callProcessToVoid(id);

            } catch (Exception e) {
                String companyNumber = (String) map.get("companyNumber");
                String personNumber = (String) map.get("personNumber");
                log.info("总公司往来单位基础信息 基础表  作废操作失败 personNumber={},companyNumber={}", personNumber, companyNumber);
                log.info(e.getMessage(), e);
            }

        }
    }


    /**
     * -----总公司往来单位财务新增
     * exec   SyncCorpSuppFinance
     *
     * @Number nvarchar(100),            ----往来单位代码
     * @invoice int,            ----是否开票资料	 客户    0  否   1 是
     * @pay int,            ----是否付款信息	 供应商    0  否   1 是
     * @accountname nvarchar(255),        ----账户名称
     * @bank nvarchar(255),                ----银行
     * @bankcode nvarchar(255),            ----银行代码
     * @accountnum  nvarchar(255),			----银行账号
     * @taxno nvarchar(255),                ----税号
     * @address nvarchar(255),            ----开票地址、电话
     * @jobdesc nvarchar(255),            ----工作说明
     * @Auditor nvarchar(100)            ----审批人  02.0100 张三
     */
    private void callProcess(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.headOfficeDealingUnitBas);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        //调用存储过程
        String dealingUnitCode = MapUtils.getString(map, "dealingUnitCode", "");
        String billingInformation = MapUtils.getString(map, "billingInformation", "");
        billingInformation = "√".equalsIgnoreCase(billingInformation) ? "1" : "0";
        String paymentInformation = MapUtils.getString(map, "paymentInformation", "");
        paymentInformation = "√".equalsIgnoreCase(paymentInformation) ? "1" : "0";
        String accountName = MapUtils.getString(map, "accountName", "");
        String bank = MapUtils.getString(map, "bank", "");
        String bankCode = MapUtils.getString(map, "bankCode", "");
        String bankAccountNumber = MapUtils.getString(map, "bankAccountNumber", "");
        String billingAddressAndTelephone = MapUtils.getString(map, "billingAddressAndTelephone", "");
        String financialDescription = MapUtils.getString(map, "financialDescription", "");
        String unifiedSocialCreditCode = MapUtils.getString(map, "unifiedSocialCreditCode", "");//税号
        String approval = MapUtils.getString(map, "approval", "");//审批人 02.0100 张三

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncCorpSuppFinance '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                dealingUnitCode, billingInformation, paymentInformation, accountName, bank,
                bankCode, bankAccountNumber, unifiedSocialCreditCode,billingAddressAndTelephone, financialDescription, approval);
        log.info("\n==========准备调用[总公司往来单位财务新增]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[总公司往来单位财务新增]存储过程执行完成");

    }

    /**
     * 调用作废存储过程
     * --------总公司往来单位基础信息   作废
     * exec  ToDoListDisable
     *
     * @Companyid nvarchar(100),            ----公司FID
     * @item nvarchar(200),            ----事项
     * @RegisDate nvarchar(100),            ----登记日期
     * @RelevantFileFID nvarchar(100)            ----相关档案FID
     */
//    private void callProcessToVoid(String bizId) {
//
//        if (StringUtils.isEmpty(bizId)) {
//            return;
//        }
//        //编写sql
//        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.headOfficeDealingUnitDetail);
//        StringBuilder sql = new StringBuilder("SELECT * from ")
//                .append(tableName).append(" where id ='")
//                .append(bizId).append("';");
//        //查询到入参
//        Map<String, Object> map = sqlService.getMap(sql.toString());
//        log.info("入参map={}", map);
//
//        //准备调用存储过程的入参
//        String fid = MapUtils.getString(map, "fid", "");//fid
//
//        //检查存储过程的入参
//        Assert.isFalse(StringUtils.isEmpty(fid), "{}不能为空", "fid");
//
//        JdbcTemplate jdbcTemplate = sqlService.getJdbcTemplateByDbCode(CloudSqlService.htEas);
//        jdbcTemplate.execute(
//                new CallableStatementCreator() {
//                    public CallableStatement createCallableStatement(Connection con) throws SQLException {
//                        CallableStatement cs = con.prepareCall("{call [HG_LINK].[hg].[dbo].ToDoListDisable (?)}");
//                        // 设置输入参数的值
//                        cs.setString(1, fid);
//                        return cs;
//                    }
//                }, new CallableStatementCallback() {
//                    public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
//                        cs.execute();
//                        return "success";// 获取输出参数的值
//                    }
//                });
//        log.info("\n=============[总公司往来单位基础信息   作废]存储过程执行完成");
//
//    }

    /**
     * -----总公司往来单位财务  作废
     * exec   CorpSuppFinanceDisable
     *
     * @Number nvarchar(100)            ----往来单位代码
     */
    private void callProcessToVoid(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.headOfficeDealingUnitBas);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());
        log.info("入参map={}", map);

        //准备调用存储过程的入参
        String dealingUnitCode = MapUtils.getString(map, "dealingUnitCode", "");

        //检查存储过程的入参
        Assert.isFalse(StringUtils.isEmpty(dealingUnitCode), "{}不能为空", "dealingUnitCode");

        //拼接sql
        String execSql = String.format("exec [HG_LINK].[hg].[dbo].CorpSuppFinanceDisable '%s'",
                dealingUnitCode);

        log.info("\n==========准备调用[总公司往来单位基础信息   作废]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[总公司往来单位基础信息   作废]存储过程执行完成");

    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity20";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            final String finalActivityCode2 = "Activity15";
            Optional<WorkItemModel> second = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode2)).findFirst();
            if (second.isPresent()) {
                WorkItemModel workItemModel = second.get();
                participant = workItemModel.getParticipant();
            }
        }


        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data) {

        //往来单位代码
        String dealingUnitCode = (String) data.get("dealingUnitCode");

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.headOfficeDealingUnitBas);

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName).append(" where dealingUnitCode ='").append(dealingUnitCode).append("' order by createdTime desc limit 1;");

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return (String) map.get("id");
    }

    /**
     * 转换成  总公司往来单位基础信息 基础表 的数据
     *
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String approval) {
        Map<String, Object> data = new HashMap<>();
        //审批人
        data.put("approval", approval);
        //审批时间
        data.put("auditDate", auditDate);

        data.put("dealingUnitCode", map.get("dealingUnitCode"));

        //状态
        data.put("financeState", map.get("financeState"));
        //开票资料
        data.put("billingInformation", map.get("billingInformation"));
        //付款信息
        data.put("paymentInformation", map.get("paymentInformation"));
        //开户名称
        data.put("accountName", map.get("accountName"));
        //银行
        data.put("bank", map.get("bank"));
        //银行代码
        data.put("bankCode", map.get("bankCode"));
        //账号
        data.put("bankAccountNumber", map.get("bankAccountNumber"));
        //统一社会信用代码
        data.put("unifiedSocialCreditCode", map.get("unifiedSocialCreditCode"));
        //开票地址、电话
        data.put("billingAddressAndTelephone", map.get("billingAddressAndTelephone"));
        //工作说明
        data.put("financialDescription", map.get("financialDescription"));
        return data;
    }

}
